// Author	: damphat@gmail.com
// Created	: 01/12/2008

#pragma once

// AutoPtr make easier to manage life time of native pointer.
// It hold & transfer & delete a native pointer.
// Why AutoPtr?
//   Because a native pointer is hard to manage in case of the function having
//   a lot of return statements, exceptions, goto, ...
//
// How to use AutoPtr?
//   AutoPtr<FileStream> f = new FileStream();
//   f->Open(...)
//   You neednot call delete operator.
//
// Note:
//   AutoPtr can transfer native pointer, but never share 1 same native pointer
//   Do not confuse with share pointer
// AutoPtr is an widely use, see http://en.wikipedia.org/wiki/Auto_ptr
template<class T>
class AutoPtr {
private:
	void operator = (const AutoPtr&);
	// = (T *p)
public:
	// constructor with a new pointer, after pass this native pointer to AutoPtr
	// the pointer will be managed by this AutoPtr object, so you should not delete
	// or give the native pointer to another function that make call delete.
	// Dev: should be explicit?
	// Dev: should be default to null
	AutoPtr(T *p) : ptr(p) 
	{ }

	// copy constructor will transfer the native pointer
	AutoPtr(AutoPtr &val) : ptr(val.ptr) {
		val.ptr = 0;
	}

	// Access element of native pointer
	T* operator -> () {	return ptr;	}
	const T* operator -> () const {	return ptr; }

	// Get function return the native pointer but the AutoPtr will continue
	// to manage pointer, you should not delete or assign to another AutoPtr.
	T* Get() { return ptr; }
	const T* Get() const { return ptr; }

	// Release function give you the native pointer, and AutoPtr wil not
	// manage the native pointer any more, so that you must delete it yourself.
	// Do not confuse with 'delete'.
	T* Release() {
		T* ret = ptr;
		ptr = 0;
		return ret;
	}

	~AutoPtr() {
		if(ptr)
			delete ptr;
	}

private:
	T* ptr;
};
